// Copyright 2019 The rhyme_lph Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// E [author] rhyme_lph
// L [email]  rhymelph@gmail.com
// m [github] https://github.com/rhymelph

import 'dart:async';

import 'package:base_plugin/base_plugin.dart';
import 'package:finance_app/generated/l10n.dart';
import 'package:finance_app/src/common/config.dart';
import 'package:finance_app/src/http_service/http_employee_contact_service.dart';
import 'package:finance_app/src/mixin/format_group_map_mixin.dart';
import 'package:finance_app/src/mixin/search_data_list_mixin.dart';
import 'package:finance_app/src/mixin/search_data_map_mixin.dart';
import 'package:finance_app/src/utils/reg_exp_utils.dart';
import 'package:finance_app/src/widgets/bottom_sheet/add_employee_bottom_sheet.dart';
import 'package:flutter/material.dart';
import 'package:finance_app/src/page/dashboard/contact/employee_contacts_page.dart';

class EmployeeContactsProvider extends BaseProvider<List<EmployeeContactEntity>>
    with SearchDataListMixin, FormatGroupMapLocalMixin<EmployeeContactEntity> {
  EmployeeContactEntity currentSelectContact;

  EmployeeContactEntity allContact;
  bool isShowAll;

  bool useLocalData = false;

  @override
  void initState() {
    super.initState();
    allContact = EmployeeContactEntity()
      ..id = -1
      ..name = S.current.all_employees
      ..title = '';
    if (isShowAll == true) {
      currentSelectContact ??= allContact;
    }
    if (data != null) {
      transformData(data, false);
    }
  }

  @override
  Future get dataFuture =>
      useLocalData ? null : HttpEmployeeContactService.contactList("open");

  void onShowAddEmployee() {
    unFocus();
    obtainContext?.call((context) async {
      final resultData = await showAddEmployeeBottomSheet(context);
      if (resultData != null) {
        EmployeeContactEntity value;

        await post(HttpEmployeeContactService.createContact(resultData),
            autoHandler: AutoHandler.Toast,
            loadingTip: S.current.loading, onSuccess: (data) {
          value = getEntityFromResult<EmployeeContactEntity>(data);
        });
        if (value != null) {
          transformData(data, false);
          onSelectContact(value);
        }
      }
    });
  }

  void onSelectContact(EmployeeContactEntity value) {
    currentSelectContact = value;
    update();
    obtainContext?.call((context) {
      Navigator.of(context).pop(value);
    });
  }

  void onAddEmployee() async {
    searchFocusNode.unfocus();
    EmployeeContactEntity value;
    await post(HttpEmployeeContactService.createContact(searchController.text),
        autoHandler: AutoHandler.Toast,
        loadingTip: S.current.loading, onSuccess: (data) {
      value = getEntityFromResult<EmployeeContactEntity>(data);
    });
    if (value != null) {
      transformData(data, false);
      onSelectContact(value);
    }
  }

  @override
  FutureOr<List<EmployeeContactEntity>> transformData(
      List<EmployeeContactEntity> d, bool isCache) {
    groupMap.clear();
    contactToMap(d);
    return d;
  }

  void contactToMap(List<EmployeeContactEntity> list) {
    sortGroupToMap(list,
        sort: (a, b) => sortNameFirst(a, b, (t) => t.name),
        group: (a) => groupFirstName(a, (t) => t.name, '*'),
        filter: (a) => onFilterSearch(searchController.text, a.name),
        itemBefore: (a, b) {
          if (isShowAll == true) {
            if (a['All'] == null) {
              a['All'] = [allContact];
            }
          }
          return useLocalData ? null : meBefore(a, b, (b) => b.userId);
        });
  }

  void onSelectEmployeeContact(EmployeeContactEntity data) {
    if (currentSelectContact == data) return;
    onSelectContact(data);
  }

  @override
  void searchRefreshData(searchData) {
    transformData(data, false);
    update();
  }
}
